/**
 * 数字系统（十进制，二进制，十六进制，八进制）
 * 
 * 在二进制中，只有 2 位数字：0 和 1，因此称为“基数 2”。在二进制中，我们这样计数：0, 1, 10, 11, 100, 101, 110, 111, …
 * 
 * C++ 中有 4 种主要的数字系统。按照流行程度排列，它们是：十进制（基数为 10）、二进制（基数为 2）、十六进制（基数为 16）和八进制（基数为 8）。
 * 
 * 以二进制输出值
 *   以二进制输出值有点困难，因为std::cout没有内置此功能。
 *   幸运的是，C++ 标准库包含一个名为 的类型std::bitset，可以为我们执行此操作（在 <bitset> 头文件中）。
 * 
 * 
 * 二进制转十进制
 *   1101 = （从右往左） 1*2^0 + 0*2^1 + 1*2^2 + 1*2^3 = 1 + 0 + 4 + 8 = 13
 * 十进制转二进制
 *   13 / 2 = 6 ... 1
 *   6 / 2  = 3 ... 0
 *   3 / 2  = 1 ... 1
 *   1 / 2  = 0 ... 1 // 一直除到商为0停止，从下往上组合起来就是二进制表示了 1101
 * 
 * 八进制转十进制
 *   15 = （从右往左） 5*8^0 + 1*8^1 = 5 + 8 = 13
 * 十进制转八进制
 *   13 / 8 = 1 ... 5
 *   1 / 8  = 0 ... 1 // 一直除到商为0停止，从下往上组合起来就是八进制表示了 15
 * 
 * 十六进制转十进制
 *   1d = （从右往左） 13*16^0 + 1*16^1 = 13 + 16 = 29
 * 十进制转十六进制
 *   29 / 16 = 1 ... d
 *   1 / 16  = 0 ... 1 // 一直除到商为0停止，从下往上组合起来就是十六进制表示了 1d
 * 
 * 二进制转八进制？
 *   答：二进制转十进制，然后十进制转八进制
 * 二进制转十六进制？
 *   答：二进制转十进制，然后十进制转十六进制
 * 其它类似情况都可以以十进制为跳板进行转换
 * 
 * 补充：
 *   有符号数和二进制补码
 *   如何处理有符号数（可以为负数）？
 *   有符号整数通常使用称为补码的方法来存储。在二进制补码中，最左边（最高有效）位用作符号位。符号位 0 表示该数为正，符号位 1 表示该数为负。
 *   
 * 将 -93 转换为 8 位有符号二进制数（使用二进制补码）
 *   1.将93转换成二进制得到：01011101
 *   2.对二进制进行补码，即反转每一个二进制位得到：10100010
 *   3.补码加一得到：10100011
 * 
 * 将 1010 0010 转换为带符号的十进制数（假设为二进制补码）。
 *   1.反转每一个二进制位得到：01011101
 *   2.加一：01011110
 *   3.0*2^0 + 1*2^1 + 1*2^2 + 1*2^3 + 1*2^4 + 0*2^5 + 1*2^6 = 2 + 4 + 8 + 16 + 64 = 94
 *   4.开头已经可以看出来这个是负数，所有答案是：-94
 * 
 * 
 */

#include <iostream>
#include <bitset>

int main() {
    int x{ 012 }; // 0 before the number means this is octal 八进制
    std::cout << x << '\n';


    int x1{ 0xF }; // 0x before the number means this is hexadecimal 十六进制
    std::cout << x1 << '\n';


    // 在 C++14 之前，不支持二进制文字。然而，十六进制文字为我们提供了一个有用的解决方法（您可能仍然在现有的代码库中看到）
    int bin{};    // assume 16-bit ints
    bin = 0x0001; // assign binary 0000 0000 0000 0001 to the variable
    bin = 0x0002; // assign binary 0000 0000 0000 0010 to the variable
    bin = 0x0004; // assign binary 0000 0000 0000 0100 to the variable
    bin = 0x0008; // assign binary 0000 0000 0000 1000 to the variable
    bin = 0x0010; // assign binary 0000 0000 0001 0000 to the variable
    bin = 0x0020; // assign binary 0000 0000 0010 0000 to the variable
    bin = 0x0040; // assign binary 0000 0000 0100 0000 to the variable
    bin = 0x0080; // assign binary 0000 0000 1000 0000 to the variable
    bin = 0x00FF; // assign binary 0000 0000 1111 1111 to the variable
    bin = 0x00B3; // assign binary 0000 0000 1011 0011 to the variable
    bin = 0xF770; // assign binary 1111 0111 0111 0000 to the variable


    // 在 C++14 中，我们可以通过使用 0b 前缀来使用二进制文字
    int bin1{};        // assume 16-bit ints
    bin1 = 0b1;        // assign binary 0000 0000 0000 0001 to the variable
    bin1 = 0b11;       // assign binary 0000 0000 0000 0011 to the variable
    bin1 = 0b1010;     // assign binary 0000 0000 0000 1010 to the variable
    bin1 = 0b11110000; // assign binary 0000 0000 1111 0000 to the variable


    // C++14 还添加了使用引号 (') 作为数字分隔符的功能
    int bin2 { 0b1011'0010 };  // assign binary 1011 0010 to the variable
    long value { 2'132'673'462 }; // much easier to read than 2132673462

    // 分隔符不能出现在值的第一个数字之前
    // int bin3 { 0b'1011 };


    // 以十进制、八进制或十六进制输出值
    // 默认情况下，C++ 以十进制输出值。但是，您可以通过使用std::dec、std::oct和std::hexI/O 操纵符来更改输出格式
    // 一旦应用，I/O 操纵器将保持为未来输出设置，直到再次更改。
    int x2 { 12 };
    std::cout << x2 << '\n'; // decimal (by default)
    std::cout << std::hex << x2 << '\n'; // hexadecimal
    std::cout << x2 << '\n'; // now hexadecimal
    std::cout << std::oct << x2 << '\n'; // octal
    std::cout << std::dec << x2 << '\n'; // return to decimal
    std::cout << x2 << '\n'; // decimal




    // std::bitset<8> means we want to store 8 bits
	std::bitset<8> bin11{ 0b1100'0101 }; // binary literal for binary 1100 0101
	std::bitset<8> bin22{ 0xC5 }; // hexadecimal literal for binary 1100 0101

	std::cout << bin11 << '\n' << bin22 << '\n';
	std::cout << std::bitset<4>{ 0b1010 } << '\n'; // create a temporary std::bitset and print it

    return 0;
}